﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;

namespace Workflows.Components.Entities.Documents
{
    [Serializable]
    public class BagOfWords : IComparableAttribute
    {
        private Dictionary<int, string> _TermPhrases;
        /// <summary></summary>
        public Dictionary<int, string> TermPhrases
        {
            get
            {
                return this._TermPhrases;
            }
            set
            {
                this._TermPhrases = value;
            }
        }

        private Dictionary<int, int> _TermFreqs;
        /// <summary></summary>
        public Dictionary<int, int> TermFreqs
        {
            get
            {
                return this._TermFreqs;
            }
            set
            {
                this._TermFreqs = value;
            }
        }

        private Dictionary<int, double> _TermWeights;
        /// <summary></summary>
        public Dictionary<int, double> TermWeights
        {
            get
            {
                return this._TermWeights;
            }
            set
            {
                this._TermWeights = value;
            }
        }

        public BagOfWords(
            Dictionary<int, string> phrases, 
            Dictionary<int, int> termFreqs, 
            Dictionary<int, double> termWeights)
        {
            this._TermPhrases = phrases;
            this._TermFreqs = termFreqs;
            this._TermWeights = termWeights;
        }

        #region IComparableAttribute Members

        public IComparableAttribute Union(IComparableAttribute attr, double membership)
        {
            if(attr !=null && attr.GetType()==typeof(BagOfWords))
            {
                BagOfWords otherBag = (BagOfWords) attr;
                if(this._TermWeights==null)
                    this._TermWeights=new Dictionary<int, double>();
                if(this._TermPhrases==null)
                    this._TermPhrases=new Dictionary<int, string>();
                if(this._TermFreqs==null)
                    this._TermFreqs=new Dictionary<int, int>();

                foreach(int termID in otherBag.TermFreqs.Keys)
                {
                    if(this._TermFreqs.ContainsKey(termID))
                    {
                        this._TermFreqs[termID] = this._TermFreqs[termID] +
                                                  (int) (membership*otherBag.TermFreqs[termID]);
                    }
                    else
                    {
                        this._TermFreqs.Add(termID, (int)(membership * otherBag.TermFreqs[termID]));
                    }
                }
                foreach (int termID in otherBag.TermPhrases.Keys)
                {
                    if (this._TermPhrases.ContainsKey(termID))
                    {
                    }
                    else
                    {
                        this._TermPhrases.Add(termID, otherBag.TermPhrases[termID]);
                    }
                }
                foreach (int termID in otherBag.TermWeights.Keys)
                {
                    if (this._TermWeights.ContainsKey(termID))
                    {
                        this._TermWeights[termID] = this._TermWeights[termID] + membership * otherBag.TermWeights[termID];
                    }
                    else
                    {
                        this._TermWeights.Add(termID, membership * otherBag.TermWeights[termID]);
                    }
                }
            }
            return this;
        }

        public IComparableAttribute Intersection(IComparableAttribute attr, double membership)
        {
            throw new NotImplementedException();
        }

        public double Compare(IComparableAttribute attr, double membership)
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}
